#include <stdio.h>      // Header file for standard file i/o.
#include <stdlib.h>     // Header file for malloc/free.

#include "image.h"
#include "math.h"

// quick and dirty bitmap loader...for 24 bit bitmaps with 1 plane only.
// See http://www.dcs.ed.ac.uk/~mxr/gfx/2d/BMP.txt for more info.
// if mesa ever gets glaux, let me know.
int ImageLoad(Image *image, char *filename) {
	FILE *file;
	unsigned long size;                 // size of the image in bytes.
	unsigned long i;                    // standard counter.
	unsigned short int planes;          // number of planes in image (must be 1)
	unsigned short int bpp;             // number of bits per pixel (must be 24)
	char temp;                          // used to convert bgr to rgb color.

	// make sure the file is there.
	if ((file = fopen(filename, "rb"))==NULL)
	{
		fprintf(stderr, "File Not Found : %s\n",filename);
		return 0;
	}

	// seek through the bmp header, up to the width/height:
	fseek(file, 18, SEEK_CUR);

	// read the width
	if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
		fprintf(stderr, "Error reading width from %s.\n", filename);
		return 0;
	}

	// read the height
	if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
		fprintf(stderr, "Error reading height from %s.\n", filename);
		return 0;
	}

	// calculate the size (assuming 24 bits or 3 bytes per pixel).
	size = image->sizeX * image->sizeY * 3;

	// read the planes
	if ((fread(&planes, 2, 1, file)) != 1) {
		fprintf(stderr, "Error reading planes from %s.\n", filename);
		return 0;
	}
	if (planes != 1) {
		fprintf(stderr, "Planes from %s is not 1: %u\n", filename, planes);
		return 0;
	}

	// read the bpp
	if ((i = fread(&bpp, 2, 1, file)) != 1) {
		fprintf(stderr, "Error reading bpp from %s.\n", filename);
		return 0;
	}
	if (bpp != 24) {
		fprintf(stderr, "Bpp from %s is not 24: %u\n", filename, bpp);
		return 0;
	}

	// seek past the rest of the bitmap header.
	fseek(file, 24, SEEK_CUR);

	// read the data.
	image->data = (unsigned char *) malloc(size);
	if (image->data == NULL) {
		fprintf(stderr, "Error allocating memory for color-corrected image data");
		return 0;
	}

	if ((i = fread(image->data, size, 1, file)) != 1) {
		fprintf(stderr, "Error reading image data from %s.\n", filename);
		return 0;
	}

	for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
		temp = image->data[i];
		image->data[i] = image->data[i+2];
		image->data[i+2] = temp;
	}

	// we're done.
	return 1;
}

/*
	Creates a new image
*/
int imageCreate(Image *image, int sizeX, int sizeY)
{
	image->sizeX = sizeX;
	image->sizeY = sizeY;

	// calculate the size (assuming 24 bits or 3 bytes per pixel).
	int size = image->sizeX * image->sizeY * 3;

	// Alocates the data.
	image->data = (unsigned char *) malloc(size);

	int i;
	for (i=0; i < size; i++)
		image->data[i] = 0;

	return 1;
}

/*
	Set a RBG value of a specific x,y pixel of one image
*/
int imageSetPixel(Image *image, int x, int y, unsigned char r, unsigned char g, unsigned char b)
{
	y = image->sizeY - y;

	unsigned long addr = (unsigned long)( (y * (image->sizeX * 3) ) + (x * 3));
	image->data[addr++] = r;
	image->data[addr++] = g;
	image->data[addr] = b;

	return 1;
}

/*
	Gets the RBG value of a specific x,y pixel of one image
*/
int imageGetPixel(Image *image, int x, int y, unsigned char *r, unsigned char *g, unsigned char *b)
{
	y = image->sizeY - y;

	unsigned long addr = (unsigned long)( (y * (image->sizeX)* 3) + (x * 3));
	*r = image->data[addr++];
	*g = image->data[addr++];
	*b = image->data[addr];

	return 1;
}
